package com.teatrace.service.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class BeanUtil {

	public static Method fetchGetMethod(Field field, Class<?> clazz)  {
		String fieldName = field.getName();
		String methodName = "get" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
		try {
			return clazz.getMethod(methodName, new Class<?>[]{});
		} catch (Exception e) {
			if(e instanceof NoSuchMethodException) {
				return null;
			}
			throw new RuntimeException(e);
		} 
	}
	
	public static Method fetchSetMethod(Field field, Class<?> clazz)  {
		String fieldName = field.getName();
		String methodName = "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
		try {
			return clazz.getMethod(methodName, field.getType());
		} catch (Exception e) {
			if(e instanceof NoSuchMethodException) {
				return null;
			}
			throw new RuntimeException(e);
		} 
	}
	
	public static Object silentlyInvoke(Method method, Object obj, Object ...args) {
		try {
			return method.invoke(obj, args);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} 
	}
	
	public static void copyDeclaredFieldIgnoreNull(Object fromObj, Object toObj, Class<?> clazz) {
		for(Field field : clazz.getDeclaredFields()) {
			Method getMethod = fetchGetMethod(field, clazz);
			if(getMethod == null) continue;
			Method setMethod = fetchSetMethod(field, clazz);
			Object value = silentlyInvoke(getMethod, fromObj);
			if(value != null) {
				silentlyInvoke(setMethod, toObj, value);
			}
		}
	}
}
